using System;
using System.Diagnostics;
using System.Xml;
using System.IO;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;

namespace MSHelpLib.HXS.Decoding
{
	/// <summary>
	/// The class <c>HHCParser</c> implements a parser for HHC contents files.
	/// </summary>	
	public sealed class HHCParser
	{
		/// <summary>
		/// Parses a HHC file and returns an ArrayList with the table of contents (TOC) tree
		/// </summary>
		/// <param name="hhcFile">string content of the hhc file</param>
		/// <param name="helpFile">CHMFile instance</param>
		/// <returns>Returns an ArrayList with the table of contents (TOC) tree</returns>
		public static ArrayList ParseHHC(string hhcFile, HXSFile helpFile)
		{
			if (helpFile!=null)
				helpFile.OnStatus("Parsing Table Of Contents File from "+helpFile.FileName);
									
			StringReader fs=new StringReader(hhcFile);			
			fs.ReadLine();
			fs.ReadLine();
			XmlTextReader xmlReader=new XmlTextReader(fs);
			
			TOCItem TocRoot=new TOCItem("Root","Root",0,"Root");
			TOCItem CurrentToc=TocRoot;
			try
			{
				while (xmlReader.Read())
				{
					try
					{
						if (xmlReader.NodeType==XmlNodeType.Whitespace) continue;
						if (xmlReader.Name!="HelpTOCNode") continue;

						if (xmlReader.NodeType==XmlNodeType.EndElement)
						{							
							CurrentToc=CurrentToc.Parent;
							if (CurrentToc==null) CurrentToc=TocRoot;
							continue;
						}
							
						if (xmlReader.NodeType==XmlNodeType.Element)
						{	
							// PluginTitle
							// Id = 
							// NodeType = TOC or Regular
							// Title
							// URL

							// If NodeType == Regular then add node to tree of contents, URL  if present is valid page to display
							// if NodeType == TOC, then URL = name of HXS file to load, & continue to add specified HXS file's TOC
							if (!xmlReader.HasAttributes)
								continue;
	                            
							string NodeType="Regular";
							try
							{
								NodeType=xmlReader.GetAttribute("NodeType");
							}
							catch
							{
								NodeType="Regular";
							}

							if (NodeType==null)
								NodeType="Regular";

							if (NodeType.ToUpper()=="TOC")
							{
								// Load HXS file (Name in Url), extract hxt file and merge TOC's into this TOC
								string Title="";
								string Url="";
								try
								{
									Title=xmlReader.GetAttribute("Title");
									Url=xmlReader.GetAttribute("Url");
									if ((Title==null) || (Title=="")) Title=Url;
									TOCItem newItem=null;									
									if (helpFile!=null)
										newItem=new TOCItem("TOC:"+Title,Url,0,helpFile.FileName);
									else
										newItem=new TOCItem("TOC:"+Title,Url,0,"");
									newItem.Parent=CurrentToc;
									newItem.AssociatedFile=helpFile;
									CurrentToc.Children.Add(newItem);								
									CurrentToc=newItem;
								}
								catch
								{
								}
							}
							else if (NodeType.ToUpper()=="REGULAR")
							{
								string Title="";
								string Url="";
								try
								{
									Title=xmlReader.GetAttribute("Title");
									Url=xmlReader.GetAttribute("Url");
									if ((Title==null) || (Title=="")) Title=Url;
									TOCItem newItem=null;
									if (helpFile!=null)
										newItem=new TOCItem(Title,Url,0,helpFile.FileName);
									else
										newItem=new TOCItem(Title,Url,0,"");
									newItem.AssociatedFile=helpFile;
									newItem.Parent=CurrentToc;
									CurrentToc.Children.Add(newItem);								
									CurrentToc=newItem;
								}
								catch
								{
								}
							}

							if (xmlReader.IsEmptyElement)
							{
								CurrentToc=CurrentToc.Parent;
								if (CurrentToc==null) CurrentToc=TocRoot;
							}
						}
					}
					catch(Exception ex)
					{
						Debug.WriteLine(ex.Message);
					}
				}				
			}
			catch(Exception ex)
			{
				Debug.WriteLine(ex.Message);
			}
			finally
			{
				// Always close file
				fs.Close();
				fs=null;
			}
					
			if (helpFile!=null)
				helpFile.OnStatus("");

			return TocRoot.Children;
		}
	}
}
